package org.aplikator.client.data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.gwt.view.client.ProvidesKey;

@SuppressWarnings("serial")
public class Record implements Serializable {

    /**
     * The key provider that provides the unique ID of a record.
     */
    public static final ProvidesKey<Record> KEY_PROVIDER = new ProvidesKey<Record>() {
        public Object getKey(Record item) {
            return item == null ? null : item.getPrimaryKey().getId();
        }
    };

    protected PrimaryKey primaryKey;

    protected Map<String, Serializable> data = new HashMap<String, Serializable>();
    protected Set<String> dirty = new HashSet<String>();

    private PrimaryKey ownerPrimaryKey;

    private String ownerPropertyId;

    @SuppressWarnings("unused")
    private Record() {
    }

    public Record(PrimaryKey primaryKey) {
        this.primaryKey = primaryKey;
    }

    public void setValue(String propertyId, Serializable value) {
        data.put(propertyId, value);
        dirty.add(propertyId);
    }

    public Serializable getValue(String propertyId) {
        return  data.get(propertyId);
    }

    public Set<String> getProperties(){
        return data.keySet();
    }

    public PrimaryKey getPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(PrimaryKey pk) {
        // if (primaryKey == -1){
        primaryKey = pk;
        // }else{
        // throw new
        // IllegalStateException("Cannot change primary key value from "+primaryKey+"to"+pk
        // );
        // }
    }

    public PrimaryKey getOwnerPrimaryKey() {
        return ownerPrimaryKey;
    }

    public void setOwnerPrimaryKey(PrimaryKey ownerPrimaryKey) {
        this.ownerPrimaryKey = ownerPrimaryKey;
    }

    public String getOwnerPropertyId() {
        return ownerPropertyId;
    }

    public void setOwnerPropertyId(String ownerPropertyId) {
        this.ownerPropertyId = ownerPropertyId;
    }

    public Record clone() {
        Record retval = new Record(new PrimaryKey(primaryKey.getEntityId(), UUID.uuid()));
        retval.ownerPrimaryKey = ownerPrimaryKey;
        retval.ownerPropertyId = ownerPropertyId;
        for (String propId : data.keySet()) {
            retval.data.put(propId, data.get(propId));
        }
        return retval;
    }

    @Override
    public String toString() {
        return data.toString();
    }

    public String toHTML() {
        StringBuilder sb = new StringBuilder();
        for (String propId : data.keySet()) {
            sb.append(propId);
            sb.append(":<b>");
            sb.append(data.get(propId) != null ? data.get(propId).toString() : "");
            sb.append("</b>");
            sb.append("<br>");

        }
        return sb.toString();
    }

    public boolean isDirty(String propertyId) {
        return dirty.contains(propertyId);
    }

    public void resetDirtyFlags(){
        dirty.clear();
    }

}
